home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / GSTYPE1.C < prev    next >
C/C++ Source or Header  |  1992-03-15  |  23KB  |  716 lines

  1. /* Copyright (C) 1990, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gstype1.c */
  21. /* Adobe Type 1 font routines for Ghostscript library */
  22. #include "math_.h"
  23. #include "memory_.h"
  24. #include "gx.h"
  25. #include "gserrors.h"
  26. #include "gxarith.h"
  27. #include "gxfixed.h"
  28. #include "gxmatrix.h"
  29. #include "gzstate.h"
  30. #include "gzdevice.h"            /* for gxchar */
  31. #include "gxdevmem.h"            /* ditto */
  32. #include "gzpath.h"
  33. #include "gxchar.h"
  34. #include "gxfont.h"
  35. #include "gxtype1.h"
  36. #include "gxop1.h"
  37.  
  38. /* Define the amount of thickening to be applied to characters. */
  39. #define type1_fill_adjust 0.25
  40.  
  41. /* Encrypt a string. */
  42. int
  43. gs_type1_encrypt(byte *dest, byte *src, uint len, crypt_state *pstate)
  44. {    register crypt_state state = *pstate;
  45.     register byte *from = src;
  46.     register byte *to = dest;
  47.     register uint count = len;
  48.     while ( count )
  49.        {    encrypt_next(*from, state, *to);
  50.         from++, to++, count--;
  51.        }
  52.     *pstate = state;
  53.     return 0;
  54. }
  55. /* Decrypt a string. */
  56. int
  57. gs_type1_decrypt(byte *dest, byte *src, uint len, crypt_state *pstate)
  58. {    register crypt_state state = *pstate;
  59.     register byte *from = src;
  60.     register byte *to = dest;
  61.     register uint count = len;
  62.     while ( count )
  63.        {    /* If from == to, we can't use the obvious */
  64.         /*    decrypt_next(*from, state, *to);    */
  65.         register byte ch = *from++;
  66.         decrypt_next(ch, state, *to);
  67.         to++, count--;
  68.        }
  69.     *pstate = state;
  70.     return 0;
  71. }
  72.  
  73. /* Define the structures for the state of a Type 1 interpreter. */
  74. /* This is the interpreter state that must be saved and restored */
  75. /* when calling a CharString subroutine. */
  76. typedef struct {
  77.     byte *ip;
  78.     crypt_state dstate;
  79. } ip_state;
  80. /* Define the stem hint tables. */
  81. /* Each stem hint table is kept sorted. */
  82. #define max_stems 3            /* arbitrary */
  83. typedef struct {
  84.     fixed v0, v1;            /* coordinates (widened a little) */
  85.     gs_fixed_point adjust_lower, adjust_upper;    /* adjustments */
  86. } stem_hint;
  87. typedef struct {
  88.     int count;
  89.     stem_hint *current;        /* cache cursor for search */
  90.     stem_hint data[max_stems];
  91. } stem_hint_table;
  92. /* This is the full state of the Type 1 interpreter. */
  93. #define ostack_size 24            /* per documentation */
  94. #define ipstack_size 10            /* per documentation */
  95. struct gs_type1_state_s {
  96.         /* The following are set at initialization */
  97.     gs_show_enum *penum;        /* show enumerator */
  98.     gs_state *pgs;            /* graphics state */
  99.     gs_type1_data *pdata;        /* font-specific data */
  100.     int charpath_flag;        /* 0 for show, 1 for false */
  101.                     /* charpath, 2 for true charpath */
  102.     int paint_type;            /* 0 for fill, non-0 for stroke */
  103.     fixed_coeff fc;            /* cached fixed coefficients */
  104.     float flatness;            /* flatness for character curves */
  105.         /* The following are updated dynamically */
  106.     fixed ostack[ostack_size];    /* the Type 1 operand stack */
  107.     int os_count;            /* # of occupied stack entries */
  108.     ip_state ipstack[ipstack_size+1];    /* control stack */
  109.     int ips_count;            /* # of occupied entries */
  110.     gs_fixed_point lsb;        /* left side bearing */
  111.     gs_fixed_point width;        /* character width */
  112.     int seac_base;            /* base character code for seac, */
  113.                     /* or -1 */
  114.         /* The following are set dynamically, */
  115.         /* but not actually used yet. */
  116.     int in_dotsection;        /* true if inside dotsection */
  117.     stem_hint_table hstem_hints;    /* horizontal stem hints */
  118.     stem_hint_table vstem_hints;    /* vertical stem hints */
  119. };
  120.  
  121. /* Export the size of the structure */
  122. const uint gs_type1_state_sizeof = sizeof(gs_type1_state);
  123.  
  124. /* Imported procedures */
  125. extern int gx_matrix_to_fixed_coeff(P3(gs_matrix *, fixed_coeff *, int));
  126.  
  127. /* Initialize a Type 1 interpreter. */
  128. /* The caller must supply a string to the first call of gs_type1_interpret. */
  129. int
  130. gs_type1_init(register gs_type1_state *pis, gs_show_enum *penum,
  131.   int charpath_flag, int paint_type, gs_type1_data *pdata)
  132. {    gs_state *pgs = penum->pgs;
  133.     pis->penum = penum;
  134.     pis->pgs = pgs;
  135.     pis->pdata = pdata;
  136.     pis->charpath_flag = charpath_flag;
  137.     pis->paint_type = paint_type;
  138.     pis->os_count = 0;
  139.     pis->ips_count = 1;
  140.     pis->seac_base = -1;
  141.     pis->in_dotsection = 0;
  142.     pis->hstem_hints.count = 0;
  143.     pis->hstem_hints.current = &pis->hstem_hints.data[0];
  144.     pis->vstem_hints.count = 0;
  145.     pis->vstem_hints.current = &pis->vstem_hints.data[0];
  146.     gx_matrix_to_fixed_coeff(&ctm_only(pgs), &pis->fc, max_coeff_bits);
  147.     /* Set the current point of the path to the origin, */
  148.     /* in anticipation of the initial [h]sbw. */
  149.     { gx_path *ppath = pgs->path;
  150.       ppath->position.x = pgs->ctm.tx_fixed;
  151.       ppath->position.y = pgs->ctm.ty_fixed;
  152.     }
  153.     /* Set the flatness to a value that is likely to produce */
  154.     /* reasonably good-looking curves, regardless of its */
  155.     /* current value in the graphics state. */
  156.     if ( (pis->flatness = pgs->flatness) > 1.0 )
  157.        {    /* With the conventional 1000-unit characters, */
  158.         /* a small "o" will be about 250 units, */
  159.         /* so set the flatness to 10 units. */
  160.         float cxx = pgs->ctm.xx, cyy = pgs->ctm.yy;
  161.         if ( cxx < 0 ) cxx = -cxx;
  162.         if ( cyy < 0 ) cyy = -cyy;
  163.         if ( cyy > cxx ) cxx = cyy;
  164.         if ( is_skewed(&pgs->ctm) )
  165.            {    float cxy = pgs->ctm.xy, cyx = pgs->ctm.yx;
  166.             if ( cxy < 0 ) cxy = -cxy;
  167.             if ( cyx < 0 ) cyx = -cyx;
  168.             if ( cxy > cxx ) cxx = cxy;
  169.             if ( cyx > cxx ) cxx = cyx;
  170.            }
  171.         pis->flatness = (cxx > 0.1 ? cxx * 10 : 1.0);
  172.        }
  173.     return 0;
  174. }
  175.  
  176. /* Tracing for type 1 interpreter */
  177. #ifdef DEBUG
  178. #  define dc(str) if ( gs_debug['1'] ) type1_trace(cip, c, str);
  179. private void near
  180. type1_trace(byte *cip, byte c, char _ds *str)
  181. {    dprintf3("[1]%lx: %02x %s\n", (ulong)(cip - 1), c, (char *)str);
  182. }
  183. #else
  184. #  define dc(str)
  185. #endif
  186.  
  187. /* Define the state used by operator procedures. */
  188. /* These macros refer to a current instance (s) of gs_op1_state. */
  189. #define sppath s.ppath
  190. #define sfc s.fc
  191. #define ptx s.px
  192. #define pty s.py
  193. #define sctx s.ctx
  194. #define scty s.cty
  195.  
  196. /* Accumulate relative coordinates */
  197. /****** THESE ARE NOT ACCURATE FOR NON-INTEGER DELTAS. ******/
  198. /* This probably doesn't make any difference in practice. */
  199. #define c_fixed(d, c) m_fixed(arg2int(d), c, sfc)
  200. #define accum_x(dx)\
  201.     ptx += c_fixed(dx, sfc.xx);\
  202.     if ( sfc.skewed ) pty += c_fixed(dx, sfc.xy)
  203. #define accum_y(dy)\
  204.     pty += c_fixed(dy, sfc.yy);\
  205.     if ( sfc.skewed ) ptx += c_fixed(dy, sfc.yx)
  206. #define accum_xy(dx,dy)\
  207.     accum_xy_proc(&s, dx, dy)
  208.  
  209. #define s (*ps)
  210. #define arg2int(f) fixed2int_var(f)
  211.  
  212. private void near
  213. accum_xy_proc(register is_ptr ps, fixed dx, fixed dy)
  214. {    int idx, idy;
  215.     ptx += m_fixed((idx = arg2int(dx)), sfc.xx, sfc),
  216.     pty += m_fixed((idy = arg2int(dy)), sfc.yy, sfc);
  217.     if ( sfc.skewed )
  218.         ptx += m_fixed(idy, sfc.yx, sfc),
  219.         pty += m_fixed(idx, sfc.xy, sfc);
  220. }
  221.  
  222. /* We round all endpoints of lines or curves */
  223. /* to the center of the nearest quarter-pixel, and suppress null lines. */
  224. /* (Rounding to the half-pixel causes too many dropouts.) */
  225. /* This saves a lot of rendering work for small characters. */
  226. #define pixel_rounded(fx)\
  227.   (((fx) | float2fixed(0.125)) & float2fixed(-0.125))
  228. #define must_draw_to(lpx, lpy, px, py)\
  229.   ((lpx = pixel_rounded(px)), (lpy = pixel_rounded(py)),\
  230.    (psub = sppath->current_subpath) == 0 ||\
  231.    (pseg = psub->last)->type == s_line_close ||\
  232.    lpx != pseg->pt.x || lpy != pseg->pt.y)
  233.  
  234. /* ------ Operator procedures ------ */
  235.  
  236. /* We put these before the interpreter to save having to write */
  237. /* prototypes for all of them. */
  238.  
  239. int
  240. gs_op1_closepath(register is_ptr ps)
  241. {    /* Note that this does NOT reset the current point! */
  242.     int code = gx_path_close_subpath(sppath);
  243.     if ( code < 0 ) return code;
  244.     return gx_path_add_point(sppath, ptx, pty);    /* put the point where it was */
  245. }
  246.  
  247. int
  248. gs_op1_sbw(register is_ptr ps, fixed sbx, fixed sby, fixed wx, fixed wy)
  249. {    register gs_type1_state *pis = ps->pis;
  250.     gs_show_enum *penum = pis->penum;
  251.     if ( penum->sb_set )
  252.         pis->lsb = penum->metrics_sb;
  253.     else
  254.         pis->lsb.x = sbx, pis->lsb.y = sby;
  255.     if ( penum->width_set )
  256.         pis->width = penum->metrics_width;
  257.     else
  258.         pis->width.x = wx, pis->width.y = wy;
  259. #ifdef DEBUG
  260. if ( gs_debug['1'] )
  261.     dprintf4("[1]sb=(%g,%g) w=(%g,%g)\n",
  262.          fixed2float(pis->lsb.x), fixed2float(pis->lsb.y),
  263.          fixed2float(pis->width.x), fixed2float(pis->width.y));
  264. #endif
  265.     accum_xy(pis->lsb.x, pis->lsb.y);
  266.     return 0;
  267. }
  268.  
  269. int
  270. gs_op1_hsbw(register is_ptr ps, fixed sbx, fixed wx)
  271. {    return gs_op1_sbw(ps, sbx, (fixed)0, wx, (fixed)0);
  272. }
  273.  
  274. int
  275. gs_op1_rrcurveto(register is_ptr ps, fixed dx1, fixed dy1,
  276.   fixed dx2, fixed dy2, fixed dx3, fixed dy3)
  277. {    fixed ptx1, pty1, ptx2, pty2;
  278.     /* Following declarations are only for must_draw_to */
  279.     fixed lpx, lpy;
  280.     subpath *psub;
  281.     segment *pseg;
  282.     accum_xy(dx1, dy1);
  283.     ptx1 = ptx, pty1 = pty;
  284.     accum_xy(dx2, dy2);
  285.     ptx2 = ptx, pty2 = pty;
  286.     accum_xy(dx3, dy3);
  287.     if ( must_draw_to(lpx, lpy, ptx, pty) )
  288.       return gx_path_add_flattened_curve(sppath, ptx1, pty1, ptx2, pty2, lpx, lpy, ps->pis->flatness);
  289.     return 0;
  290. }
  291.  
  292. #undef s
  293.  
  294. /* ------ Main interpreter ------ */
  295.  
  296. /* Continue interpreting a Type 1 CharString. */
  297. /* If str != 0, it is taken as the byte string to interpret. */
  298. /* Return 0 on successful completion, <0 on error, */
  299. /* or >0 when client intervention is required. */
  300. /* The int * argument is where the character is stored for seac, */
  301. /* or the othersubr # for callothersubr. */
  302. private void near type1_hstem(P3(gs_type1_state *, fixed, fixed));
  303. private void near type1_vstem(P3(gs_type1_state *, fixed, fixed));
  304. private stem_hint *near type1_stem(P3(stem_hint_table *, fixed, fixed));
  305. private int near type1_endchar(P3(gs_type1_state *, gs_state *, gx_path *));
  306. int
  307. gs_type1_interpret(register gs_type1_state *pis, byte *str, int *pindex)
  308. {    gs_state *pgs = pis->pgs;
  309.     gs_type1_data *pdata = pis->pdata;
  310.     gs_op1_state s;
  311.     fixed cstack[ostack_size];
  312. #define cs0 cstack[0]
  313. #define ics0 fixed2int_var(cs0)
  314. #define cs1 cstack[1]
  315. #define ics1 fixed2int_var(cs1)
  316. #define cs2 cstack[2]
  317. #define ics2 fixed2int_var(cs2)
  318. #define cs3 cstack[3]
  319. #define ics3 fixed2int_var(cs3)
  320. #define cs4 cstack[4]
  321. #define ics4 fixed2int_var(cs4)
  322. #define cs5 cstack[5]
  323. #define ics5 fixed2int_var(cs5)
  324.     register fixed _ss *csp;
  325. #define clear csp = cstack - 1
  326.     ip_state *ipsp = &pis->ipstack[pis->ips_count - 1];
  327.     register byte *cip;
  328.     register crypt_state state;
  329.     register int c;
  330.     int code = 0;
  331.     fixed ftx = pgs->ctm.tx_fixed, fty = pgs->ctm.ty_fixed;
  332.     fixed lpx, lpy;
  333.     subpath *psub;
  334.     segment *pseg;
  335.  
  336.     sppath = pgs->path;
  337.     s.pis = pis;
  338.     sfc = pis->fc;
  339.     ptx = sppath->position.x;
  340.     pty = sppath->position.y;
  341.  
  342.     /* Copy the operand stack out of the saved state. */
  343.     if ( pis->os_count == 0 )
  344.        {    clear;
  345.        }
  346.     else
  347.        {    memcpy(cstack, pis->ostack, pis->os_count * sizeof(fixed));
  348.         csp = &cstack[pis->os_count - 1];
  349.        }
  350.  
  351.     if ( str == 0 ) goto cont;
  352.     cip = str;
  353. call:    state = crypt_charstring_seed;
  354.        {    int skip = pdata->lenIV;
  355.         /* Skip initial random bytes */
  356.         for ( ; skip > 0; --skip )
  357.            {    decrypt_skip_next(*cip, state); ++cip;
  358.            }
  359.        }
  360.     goto top;
  361. cont:    cip = ipsp->ip;
  362.     state = ipsp->dstate;
  363. top:    while ( 1 )
  364.      { uint c0;
  365.        c = decrypt_this((c0 = *cip++), state);
  366.        decrypt_skip_next(c0, state);
  367.        switch ( (char_command)c )
  368.        {
  369. #define cnext clear; break
  370.     case c_hstem: dc("hstem")
  371.         type1_hstem(pis, cs0, cs1);
  372.         cnext;
  373.     case c_vstem: dc("vstem")
  374.         type1_vstem(pis, cs0, cs1);
  375.         cnext;
  376.     case c_vmoveto: dc("vmoveto")
  377.         accum_y(cs0);
  378. move:        /* Round to the nearest center of a quarter-pixel. */
  379.         if ( must_draw_to(lpx, lpy, ptx, pty) )
  380.             code = gx_path_add_point(sppath, lpx, lpy);
  381.         goto cc;
  382.     case c_rlineto: dc("rlineto")
  383.         accum_xy(cs0, cs1);
  384. line:        /* Round to the nearest center of a quarter-pixel. */
  385.         if ( must_draw_to(lpx, lpy, ptx, pty) )
  386.             code = gx_path_add_line(sppath, lpx, lpy);
  387. cc:        if ( code < 0 ) return code;
  388. pp:
  389. #ifdef DEBUG
  390. if ( gs_debug['1'] )
  391.         dprintf2("[1]pt=(%g,%g)\n",
  392.              fixed2float(ptx), fixed2float(pty));
  393. #endif
  394.         cnext;
  395.     case c_hlineto: dc("hlineto")
  396.         accum_x(cs0);
  397.         goto line;
  398.     case c_vlineto: dc("vlineto")
  399.         accum_y(cs0);
  400.         goto line;
  401.     case c_rrcurveto: dc("rrcurveto")
  402.         code = gs_op1_rrcurveto(&s, cs0, cs1, cs2, cs3, cs4, cs5);
  403.         goto cc;
  404.     case c_closepath: dc("closepath")
  405.         code = gs_op1_closepath(&s);
  406.         goto cc;
  407.     case c_callsubr: dc("callsubr")
  408.        {    int index = fixed2int_var(*csp);
  409.         byte *nip;
  410.         code = (*pdata->subr_proc)(pdata, index, &nip);
  411.         if ( code < 0 ) return_error(code);
  412.         --csp;
  413.         ipsp->ip = cip, ipsp->dstate = state;
  414.         ++ipsp;
  415.         cip = nip;
  416.        }
  417.         goto call;
  418.     case c_return: dc("return")
  419.         --ipsp;
  420.         goto cont;
  421.     case c_escape: dc("escape:")
  422.         decrypt_next(*cip, state, c); ++cip;
  423.         switch ( (char_extended_command)c )
  424.            {
  425.         case ce_dotsection: dc("  dotsection")
  426.             pis->in_dotsection = !pis->in_dotsection;
  427.             cnext;
  428.         case ce_vstem3: dc("  vstem3")
  429.             type1_vstem(pis, cs0, cs1);
  430.             type1_vstem(pis, cs2, cs3);
  431.             type1_vstem(pis, cs4, cs5);
  432.             cnext;
  433.         case ce_hstem3: dc("  hstem3")
  434.             type1_hstem(pis, cs0, cs1);
  435.             type1_hstem(pis, cs2, cs3);
  436.             type1_hstem(pis, cs4, cs5);
  437.             cnext;
  438.         case ce_seac: dc("  seac")
  439.             /* Do the accent now.  When it finishes */
  440.             /* (detected in endchar), do the base character. */
  441.             pis->seac_base = ics3;
  442.             /* Adjust the origin of the coordinate system */
  443.             /* for the accent (endchar puts it back). */
  444.             ptx = ftx, pty = fty;
  445.             cs1 -= cs0;     /* subtract off asb */
  446.             accum_xy(cs1, cs2);
  447.             sppath->position.x = ptx;
  448.             sppath->position.y = pty;
  449.             pis->os_count = 0;    /* clear */
  450.             /* Give control back to the caller, who must */
  451.             /* re-invoke the interpreter with the seac string. */
  452.             *pindex = ics4;
  453.             return type1_result_seac;
  454.         case ce_sbw: dc("  sbw")
  455.             code = gs_op1_sbw(&s, cs0, cs1, cs2, cs3);
  456.             goto cc;
  457.         case ce_div: dc("  div")
  458.             csp[-1] = float2fixed((float)csp[-1] / (float)*csp);
  459.             --csp; goto pushed;
  460.         case ce_undoc15: dc("  undoc15")
  461.             /*
  462.              * NOTE: this opcode is not documented by Adobe,
  463.              * but is used in some Adobe fonts.  I have no idea
  464.              * what it is supposed to do.
  465.              */
  466.             cnext;
  467.         case ce_callothersubr: dc("  callothersubr")
  468.            {    int scount = csp - cstack;
  469.             *pindex = fixed2int_var(*csp);
  470.             /* Update path position so it will be right */
  471.             /* when we come back in. */
  472.             sppath->position.x = ptx;
  473.             sppath->position.y = pty;
  474.             /* Exit to caller */
  475.             ipsp->ip = cip, ipsp->dstate = state;
  476.             pis->os_count = scount;
  477.             pis->ips_count = ipsp - &pis->ipstack[0] + 1;
  478.             if ( scount )
  479.                 memcpy(pis->ostack, cstack,
  480.                        scount * sizeof(fixed));
  481.             return type1_result_callothersubr;
  482.            }
  483.         case ce_pop: dc("  pop")
  484.             ++csp;
  485.             code = (*pdata->pop_proc)(pdata, csp);
  486.             if ( code < 0 ) return_error(code);
  487.             goto pushed;
  488.         case ce_setcurrentpoint: dc("  setcurrentpoint")
  489.             ptx = ftx, pty = fty;
  490.             accum_xy(cs0, cs1);
  491.             goto pp;
  492.         default:
  493.             return_error(gs_error_invalidfont);
  494.            }
  495.         break;
  496.     case c_hsbw: dc("hsbw")
  497.         code = gs_op1_hsbw(&s, cs0, cs1);
  498.         goto cc;
  499.     case c_endchar: dc("endchar")
  500.         if ( pis->seac_base >= 0 )
  501.            {    /* We just finished the accent of a seac. */
  502.             /* Do the base character. */
  503.             *pindex = pis->seac_base;
  504.             pis->seac_base = -1;
  505.             /* Restore the coordinate system origin */
  506.             sppath->position.x = ftx;
  507.             sppath->position.y = fty;
  508.             pis->os_count = 0;    /* clear */
  509.             /* Clear the ipstack, in case the accent ended */
  510.             /* inside a subroutine. */
  511.             pis->ips_count = 1;
  512.             /* Give control back to the caller, who must */
  513.             /* re-invoke the interpreter with the */
  514.             /* base character string. */
  515.             return type1_result_seac;
  516.            }
  517.         /* This is a real endchar.  Handle it below. */
  518.         return type1_endchar(pis, pgs, sppath);
  519.     case c_rmoveto: dc("rmoveto")
  520.         accum_xy(cs0, cs1);
  521.         goto move;
  522.     case c_hmoveto: dc("hmoveto")
  523.         accum_x(cs0);
  524.         goto move;
  525.     case c_vhcurveto: dc("vhcurveto")
  526.         code = gs_op1_rrcurveto(&s, (fixed)0, cs0, cs1, cs2, cs3, (fixed)0);
  527.         goto cc;
  528.     case c_hvcurveto: dc("hvcurveto")
  529.         code = gs_op1_rrcurveto(&s, cs0, (fixed)0, cs1, cs2, (fixed)0, cs3);
  530.         goto cc;
  531.     /* Fill up the dispatch up to 32. */
  532.     case c_undef0: case c_undef2:
  533.     case c_undef15:
  534.     case c_undef16: case c_undef17: case c_undef18: case c_undef19:
  535.     case c_undef20: case c_undef23:
  536.     case c_undef24: case c_undef25: case c_undef26: case c_undef27:
  537.     case c_undef28: case c_undef29:
  538.         return_error(gs_error_invalidfont);
  539.     /* Fill up the dispatch for 1-byte numbers. */
  540. #define icase(n) case n:
  541. #define ncase(n) case n: *++csp = int2fixed(c_value_num1(n)); goto pushed;
  542. #define icase10(n)\
  543.   icase(n) icase(n+1) icase(n+2) icase(n+3) icase(n+4)\
  544.   icase(n+5) icase(n+6) icase(n+7) icase(n+8) icase(n+9)
  545. #define ncase10(n)\
  546.   ncase(n) ncase(n+1) ncase(n+2) ncase(n+3) ncase(n+4)\
  547.   ncase(n+5) ncase(n+6) ncase(n+7) ncase(n+8) ncase(n+9)
  548.     icase(32) icase(33) icase(34)
  549.     icase(35) icase(36) icase(37) icase(38) icase(39)
  550.     icase10(40)
  551.     icase10(50) icase10(60) icase10(70) icase10(80) icase10(90)
  552.     icase10(100) icase10(110) goto pi; ncase10(120) ncase10(130) ncase10(140)
  553.     ncase10(150) icase10(160) icase10(170) icase10(180) icase10(190)
  554.     icase10(200) icase10(210) icase10(220) icase10(230)
  555.     icase(240) icase(241) icase(242) icase(243) icase(244)
  556.     icase(245) icase(246)
  557. pi:        *++csp = int2fixed(c_value_num1(c));
  558. pushed:
  559. #ifdef DEBUG
  560. if ( gs_debug['1'] )
  561.         dprintf3("[1]%d: (%d) %f\n",
  562.              (int)(csp - cstack), c, fixed2float(*csp));
  563. #endif
  564.         break;
  565.     /* Handle 2-byte positive numbers. */
  566. #define case_num2(n)\
  567.   case c_num2+n: *++csp = int2fixed(c_value_num2(c_num2+n, 0))
  568.     case_num2(0); goto pos2;
  569.     case_num2(1); goto pos2;
  570.     case_num2(2); goto pos2;
  571.     case_num2(3);
  572. #undef case_num2
  573. pos2:       {    c0 = *cip++;
  574.         *csp += int2fixed(decrypt_this(c0, state));
  575.         decrypt_skip_next(c0, state);
  576.        }    goto pushed;
  577.     /* Handle 2-byte negative numbers. */
  578. #define case_num3(n)\
  579.   case c_num3+n: *++csp = int2fixed(c_value_num3(c_num3+n, 0))
  580.     case_num3(0); goto neg2;
  581.     case_num3(1); goto neg2;
  582.     case_num3(2); goto neg2;
  583.     case_num3(3);
  584. #undef case_num3
  585. neg2:       {    c0 = *cip++;
  586.         *csp -= int2fixed(decrypt_this(c0, state));
  587.         decrypt_skip_next(c0, state);
  588.        }    goto pushed;
  589.     /* Handle 5-byte numbers. */
  590.     case c_num4:
  591.        {    uint c1, c2;
  592.         long lw;
  593.         decrypt_next(*cip, state, c0);
  594.         decrypt_next(cip[1], state, c1);
  595.         decrypt_next(cip[2], state, c2);
  596.         decrypt_next(cip[3], state, lw);
  597.         cip += 4;
  598.         lw += (ulong)c0 << 24;
  599.         lw += (ulong)c1 << 16;
  600.         lw += c2 << 8;
  601.         *++csp = int2fixed(lw);
  602.         if ( lw != fixed2int_var(*csp) )
  603.             return_error(gs_error_rangecheck);
  604.        }    goto pushed;
  605.        }
  606.      }
  607. }
  608.  
  609. /* Add a horizontal stem hint. */
  610. private void near
  611. type1_hstem(gs_type1_state *pis, fixed y, fixed dy)
  612. {    stem_hint *psh;
  613.     if ( dy < 0 ) y += dy, dy = -dy;
  614.     psh = type1_stem(&pis->hstem_hints, y, dy);
  615.     if ( psh == 0 ) return;
  616.     /* Compute adjustments here */
  617. }
  618.  
  619. /* Add a vertical stem hint. */
  620. private void near
  621. type1_vstem(gs_type1_state *pis, fixed x, fixed dx)
  622. {    stem_hint *psh;
  623.     if ( dx < 0 ) x += dx, dx = -dx;
  624.     psh = type1_stem(&pis->vstem_hints, x, dx);
  625.     if ( psh == 0 ) return;
  626.     /* Compute adjustments here */
  627. }
  628.  
  629. /* Add a stem hint, keeping the table sorted. */
  630. /* Return the stem hint pointer, or 0 if the table is full. */
  631. private stem_hint *near
  632. type1_stem(stem_hint_table *psht, fixed v0, fixed d)
  633. {    stem_hint *bot = &psht->data[0];
  634.     stem_hint *top = bot + psht->count;
  635.     if ( psht->count >= max_stems ) return 0;
  636.     while ( top > bot && v0 < top[-1].v0 )
  637.        {    *top = top[-1];
  638.         top--;
  639.        }
  640.     top->v0 = v0, top->v1 = v0 + d;
  641.     psht->count++;
  642.     return top;
  643. }
  644.  
  645. /* Handle the end of a character.  We break this out into a separate */
  646. /* procedure so as not to overwhelm the optimizing compilers. */
  647. private int near
  648. type1_endchar(gs_type1_state *pis, gs_state *pgs, gx_path *ppath)
  649. {    fixed ftx = pgs->ctm.tx_fixed, fty = pgs->ctm.ty_fixed;
  650.     int code;
  651.     /* Set the current point to the character origin: */
  652.     /* the 'show' loop will take care of adding in */
  653.     /* the width we supply to setcharwidth/cachedevice. */
  654.     gx_path_add_point(ppath, ftx, fty);
  655.     if ( pis->charpath_flag )
  656.        {    code = gs_setcharwidth(pis->penum, pgs,
  657.                 fixed2float(pis->width.x),
  658.                 fixed2float(pis->width.y));
  659.         if ( code < 0 ) return code;
  660.         /* Merge the path into its parent */
  661.         return gx_path_add_path(pgs->saved->path, ppath);
  662.        }
  663.        {    gs_rect bbox;
  664.         code = gs_pathbbox(pgs, &bbox);
  665.         if ( code < 0 )        /* must be a null path */
  666.            {    bbox.p.x = bbox.p.y = bbox.q.x = bbox.q.y = 0;
  667.            }
  668. #ifdef DEBUG
  669. if ( gs_debug['1'] )
  670.         dprintf4("[1]bbox=(%g,%g),(%g,%g)\n",
  671.              bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
  672. #endif
  673.            {    /* Expand the bounding box to encompass */
  674.             /* the width of the stroke (if stroking). */
  675.             /* setcachedevice also adds 1 or 2 pixels, */
  676.             /* so we don't have to worry about rounding. */
  677.             if ( pis->paint_type )
  678.                {    float adjust = gs_currentlinewidth(pgs);
  679.                 if ( adjust < 1 ) adjust = 1;
  680.                 /****** SHOULD SCALE ******/
  681.                 bbox.p.x -= adjust;
  682.                 bbox.p.y -= adjust;
  683.                 bbox.q.x += adjust;
  684.                 bbox.q.y += adjust;
  685.                }
  686.            }
  687.         code = gs_setcachedevice(pis->penum, pgs,
  688.                 fixed2float(pis->width.x),
  689.                 fixed2float(pis->width.y),
  690.                 bbox.p.x, bbox.p.y,
  691.                 bbox.q.x, bbox.q.y);
  692.         if ( code < 0 ) return code;
  693.        }
  694.     /* We've already constructed the path: */
  695.     /* translate it so it matches the cache device. */
  696.     gx_path_translate(pgs->path, pgs->ctm.tx_fixed - ftx,
  697.               pgs->ctm.ty_fixed - fty);
  698.     if ( code < 0 ) return code;
  699.     /******
  700.      ****** The adjust parameter is a hack to make
  701.      ****** characters come out more bold, since we
  702.      ****** don't look at the hints.
  703.      ******/
  704.     gx_color_load(pgs->dev_color, pgs);
  705.     return (pis->paint_type ? gs_stroke(pgs) :
  706.         gs_fill_adjust(pgs, float2fixed(type1_fill_adjust)));
  707. }
  708.  
  709. /* Pop a (fixed) number off the internal stack. */
  710. /* The client uses this to get the arguments for an OtherSubr. */
  711. int
  712. gs_type1_pop(gs_type1_state *pis, fixed *pf)
  713. {    *pf = pis->ostack[--(pis->os_count)];
  714.     return 0;
  715. }
  716.